using BepuUtilities.Collections;
using System;
using System.Runtime.CompilerServices;

namespace BepuPhysics
{
    // 将句柄整数包装在类型化容器中可以减少将句柄混淆为内存中索引的可能性,或者混淆静电句柄/正文句柄/约束句柄的可能性。
    // 值得注意的是,这些类型实际上什么都不做-它们严格地存在,所以避免一些常见的陷阱。
    // 因此,如果用户有将这些作为整数处理的高级用例是有帮助的,那么他们可以毫不费力地这样做。

    /// <summary>
    /// 属于仿真的Body集合的实体的唯一标识符。
    /// </summary>
    public struct BodyHandle : IEquatable<BodyHandle>, IEqualityComparerRef<BodyHandle>
    {
        /// <summary>
        /// 句柄到内存映射表中的索引,用于查找正文的当前内存位置。
        /// 在身体的生命周期内,此值不会(也不能)更改,但表所指向的内存可能会更改。
        /// </summary>
        public int Value;

        public BodyHandle(int value)
        {
            Value = value;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public bool Equals(BodyHandle other)
        {
            return Value == other.Value;
        }
        public override bool Equals(object obj)
        {
            return Equals((BodyHandle)obj);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool operator ==(BodyHandle a, BodyHandle b)
        {
            return a.Value == b.Value;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool operator !=(BodyHandle a, BodyHandle b)
        {
            return a.Value != b.Value;
        }
        public override int GetHashCode()
        {
            return Value.GetHashCode();
        }

        public override string ToString()
        {
            return Value.ToString();
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int Hash(ref BodyHandle item)
        {
            return item.Value;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public bool Equals(ref BodyHandle a, ref BodyHandle b)
        {
            return a.Value == b.Value;
        }
    }

    /// <summary>
    /// 属于模拟的Statics集合的静电的唯一标识符。
    /// </summary>
    public struct StaticHandle : IEquatable<StaticHandle>, IEqualityComparerRef<StaticHandle>
    {
        /// <summary>
        /// 句柄到内存映射表中的索引,用于查找正文的当前内存位置。
        /// 在身体的生命周期内,此值不会(也不能)更改,但表所指向的内存可能会更改。
        /// </summary>
        public int Value;

        public StaticHandle(int value)
        {
            Value = value;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public bool Equals(StaticHandle other)
        {
            return Value == other.Value;
        }
        public override bool Equals(object obj)
        {
            return Equals((StaticHandle)obj);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool operator ==(StaticHandle a, StaticHandle b)
        {
            return a.Value == b.Value;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool operator !=(StaticHandle a, StaticHandle b)
        {
            return a.Value != b.Value;
        }
        public override int GetHashCode()
        {
            return Value.GetHashCode();
        }

        public override string ToString()
        {
            return Value.ToString();
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int Hash(ref StaticHandle item)
        {
            return item.Value;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public bool Equals(ref StaticHandle a, ref StaticHandle b)
        {
            return a.Value == b.Value;
        }
    }

    /// <summary>
    /// 属于仿真求解器的约束的唯一标识符。
    /// </summary>
    public struct ConstraintHandle : IEquatable<ConstraintHandle>, IEqualityComparerRef<ConstraintHandle>
    {
        /// <summary>
        /// 句柄到内存映射表中的索引,用于查找约束的当前内存位置。
        /// 在约束的生存期内,该值不会(也不能)更改,但表指向的内存可能会更改。
        /// </summary>
        public int Value;

        public ConstraintHandle(int index)
        {
            Value = index;
        }


        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public bool Equals(ConstraintHandle other)
        {
            return Value == other.Value;
        }
        public override bool Equals(object obj)
        {
            return Equals((ConstraintHandle)obj);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool operator ==(ConstraintHandle a, ConstraintHandle b)
        {
            return a.Value == b.Value;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool operator !=(ConstraintHandle a, ConstraintHandle b)
        {
            return a.Value != b.Value;
        }
        public override int GetHashCode()
        {
            return Value.GetHashCode();
        }

        public override string ToString()
        {
            return Value.ToString();
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int Hash(ref ConstraintHandle item)
        {
            return item.Value;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public bool Equals(ref ConstraintHandle a, ref ConstraintHandle b)
        {
            return a.Value == b.Value;
        }
    }
}
